//
// DO NOT MODIFY THIS FILE - it is generated using templatec on GrammarOutput.t
//
package lpg;

import java.io.PrintWriter;
import lpg.util.DispatchWriter; /* GrammarOutput.t:1 */
import lpg.util.Utility; /* GrammarOutput.t:1 */

class GrammarOutput
{
    private PrintWriter out = null;

    public void setOut(PrintWriter pw)
    {
        out = pw;
    }

    public void run()
    {
        out.write("\nPredefined Macros:\n"); /* GrammarOutput.t:1~3 */
        for (int i = 0, n = action.localMacroTableSize(); i < n; i++) /* GrammarOutput.t:4 */
        { /* GrammarOutput.t:5 */
            out.write("\n    "); /* GrammarOutput.t:6~7 */
            out.print(action.getLocalMacro(i).name()); /* GrammarOutput.t:7 */
        } /* GrammarOutput.t:8 */

        // /* GrammarOutput.t:10 */
        // Print the filter macros, if any. /* GrammarOutput.t:11 */
        // /* GrammarOutput.t:12 */
        if (action.filterMacroTableSize() > 0) /* GrammarOutput.t:13 */
        { /* GrammarOutput.t:14 */
            out.write("\n\n\nFilter Macros:\n"); /* GrammarOutput.t:15~19 */
            for (int i = 0, n = action.filterMacroTableSize(); i < n; i++) /* GrammarOutput.t:20 */
            { /* GrammarOutput.t:21 */
                out.write("\n    "); /* GrammarOutput.t:22~23 */
                out.print(option.escape); /* GrammarOutput.t:23 */
                out.print(action.getFilterMacro(i).name()); /* GrammarOutput.t:23 */
            } /* GrammarOutput.t:24 */
        } /* GrammarOutput.t:25 */

        // /* GrammarOutput.t:27 */
        // Print the Exported symbols, if any. /* GrammarOutput.t:28 */
        // /* GrammarOutput.t:29 */
        if (!parser.exports.isEmpty()) /* GrammarOutput.t:30 */
        { /* GrammarOutput.t:31 */
            out.write("\n\n\nExported symbols:\n"); /* GrammarOutput.t:32~36 */
            for (int i = 0, n = parser.exports.size(); i < n; i++) /* GrammarOutput.t:37 */
            { /* GrammarOutput.t:38 */
                out.write("\n    "); /* GrammarOutput.t:39~40 */
                displaySymbol(lexStream.nameString(parser.exports.get(i))); /* GrammarOutput.t:41 */
            } /* GrammarOutput.t:42 */
        } /* GrammarOutput.t:43 */

        // /* GrammarOutput.t:45 */
        // Print the Macro definitions, if any. /* GrammarOutput.t:46 */
        // /* GrammarOutput.t:47 */
        if (!macroTable.isEmpty()) /* GrammarOutput.t:48 */
        { /* GrammarOutput.t:49 */
            out.write("\n\n\nDefined Symbols:\n\n"); /* GrammarOutput.t:50~55 */
            for (int i = 0, n = macroTable.size(); i < n; i++) /* GrammarOutput.t:56 */
            { /* GrammarOutput.t:57 */
                MacroSymbol macro = macroTable.element(i); /* GrammarOutput.t:58 */
                int blockToken = macro.block(); /* GrammarOutput.t:59 */
                if (blockToken != 0) // a defined macro /* GrammarOutput.t:60 */
                { /* GrammarOutput.t:61 */
                    out.write("\n\n    "); /* GrammarOutput.t:62~64 */
                    out.print(macro.name()); /* GrammarOutput.t:64 */
                    out.write("\n"); /* GrammarOutput.t:64~65 */
                    writer.setIndentSize(4); /* GrammarOutput.t:66 */
                    out.print(lexStream.tokenString(blockToken)); /* GrammarOutput.t:67 */
                    out.write("\n"); /* GrammarOutput.t:67~68 */
                    writer.setIndentSize(0); /* GrammarOutput.t:69 */
                } /* GrammarOutput.t:70 */
            } /* GrammarOutput.t:71 */
        } /* GrammarOutput.t:72 */

        // /* GrammarOutput.t:74 */
        // Print the Aliases, if any. /* GrammarOutput.t:75 */
        // /* GrammarOutput.t:76 */
        if (!parser.aliases.isEmpty()) /* GrammarOutput.t:77 */
        { /* GrammarOutput.t:78 */
            out.write("\n\n"); /* GrammarOutput.t:79~81 */
            if (parser.aliases.size() == 1) /* GrammarOutput.t:82 */
                out.write("Alias:"); /* GrammarOutput.t:83 */
            else /* GrammarOutput.t:84 */
                out.write("Aliases:"); /* GrammarOutput.t:85 */
            out.write("\n"); /* GrammarOutput.t:86~87 */
            for (int i = 0, n = parser.aliases.size(); i < n; i++) /* GrammarOutput.t:88 */
            { /* GrammarOutput.t:89 */
                AliasDefinition alias = parser.aliases.get(i); /* GrammarOutput.t:90 */
                out.write("\n    "); /* GrammarOutput.t:91~92 */
                writer.beginAutoWrap(); /* GrammarOutput.t:93 */
                displaySymbol(lexStream.tokenString(alias.lhsIndex)); /* GrammarOutput.t:94 */
                out.write("::="); /* GrammarOutput.t:95 */
                displaySymbol(lexStream.tokenString(alias.rhsIndex)); /* GrammarOutput.t:96 */
                writer.endAutoWrap(); /* GrammarOutput.t:97 */
            } /* GrammarOutput.t:98 */
        } /* GrammarOutput.t:99 */

        // /* GrammarOutput.t:101 */
        // Print special symbols. /* GrammarOutput.t:102 */
        // /* GrammarOutput.t:103 */
        if (!parser.startIndexes.isEmpty()) /* GrammarOutput.t:104 */
        { /* GrammarOutput.t:105 */
            out.write("\n\n\nStart:\n"); /* GrammarOutput.t:106~110 */
            for (int i = 0, n = parser.startIndexes.size(); i < n; i++) /* GrammarOutput.t:111 */
            { /* GrammarOutput.t:112 */
                out.write("\n    "); /* GrammarOutput.t:113~114 */
                displaySymbol(grammar.retrieveString(grammar.startSymbol.get(i).symbolIndex())); /* GrammarOutput.t:115 */
            } /* GrammarOutput.t:116 */
        } /* GrammarOutput.t:117 */
        if (parser.identifierIndex != 0) /* GrammarOutput.t:118 */
        { /* GrammarOutput.t:119 */
            out.write("\n\nIdentifier:\n\n    "); /* GrammarOutput.t:120~124 */
            displaySymbol(grammar.retrieveString(grammar.identifierImage)); /* GrammarOutput.t:125 */
        } /* GrammarOutput.t:126 */
        if (parser.eolIndex != 0) /* GrammarOutput.t:127 */
        { /* GrammarOutput.t:128 */
            out.write("\n\nEol:\n\n    "); /* GrammarOutput.t:129~133 */
            displaySymbol(grammar.retrieveString(grammar.eolImage)); /* GrammarOutput.t:134 */
        } /* GrammarOutput.t:135 */
        if (parser.eofIndex != 0) /* GrammarOutput.t:136 */
        { /* GrammarOutput.t:137 */
            out.write("\n\nEof:\n\n    "); /* GrammarOutput.t:138~142 */
            displaySymbol(grammar.retrieveString(grammar.eofImage)); /* GrammarOutput.t:143 */
        } /* GrammarOutput.t:144 */
        if (parser.errorIndex != 0) /* GrammarOutput.t:145 */
        { /* GrammarOutput.t:146 */
            out.write("\n\nError:\n\n    "); /* GrammarOutput.t:147~151 */
            displaySymbol(grammar.retrieveString(grammar.errorImage)); /* GrammarOutput.t:152 */
        } /* GrammarOutput.t:153 */

        // /* GrammarOutput.t:155 */
        // Print the terminals. /* GrammarOutput.t:156 */
        // /* GrammarOutput.t:157 */
        out.write("\n\nTerminals:\n"); /* GrammarOutput.t:158~161 */
        for (int i = grammar.firstTerminal(); i <= grammar.lastTerminal(); i++) /* GrammarOutput.t:162 */
        { /* GrammarOutput.t:163 */
            if (i != grammar.empty && !grammar.isKeyword(i)) /* GrammarOutput.t:164 */
            { /* GrammarOutput.t:165 */
                out.write("\n    "); /* GrammarOutput.t:166~167 */
                displaySymbol(grammar.retrieveString(i)); /* GrammarOutput.t:168 */
            } /* GrammarOutput.t:169 */
        } /* GrammarOutput.t:170 */

        out.write("\n\n\nSoft Keywords:\n"); /* GrammarOutput.t:172~176 */
        for (int i = grammar.firstTerminal(); i <= grammar.lastTerminal(); i++) /* GrammarOutput.t:177 */
        { /* GrammarOutput.t:178 */
            if (i != grammar.empty && grammar.isKeyword(i)) /* GrammarOutput.t:179 */
            { /* GrammarOutput.t:180 */
                out.write("\n    "); /* GrammarOutput.t:181~182 */
                displaySymbol(grammar.retrieveString(i)); /* GrammarOutput.t:183 */
            } /* GrammarOutput.t:184 */
        } /* GrammarOutput.t:185 */

        // /* GrammarOutput.t:187 */
        // Print the Rules /* GrammarOutput.t:188 */
        // /* GrammarOutput.t:189 */
        out.write("\n\n\nRules:\n"); /* GrammarOutput.t:190~194 */
        // /* GrammarOutput.t:195 */
        // First, print the start rules. /* GrammarOutput.t:196 */
        // /* GrammarOutput.t:197 */
        out.write("\n0"); /* GrammarOutput.t:198~199 */
        writer.padToColumn(5); /* GrammarOutput.t:200 */
        writer.beginAutoWrap(); /* GrammarOutput.t:201 */
        Grammar.RuleElement startRule = grammar.rules.get(0); /* GrammarOutput.t:202 */
        displaySymbol(grammar.retrieveString(startRule.lhs)); /* GrammarOutput.t:203 */
        out.write("::="); /* GrammarOutput.t:204 */
        displaySymbol(grammar.restoreSymbol( /* GrammarOutput.t:205 */
                grammar.retrieveString(grammar.rhsSym.get(startRule.rhsIndex)))); /* GrammarOutput.t:206 */
        writer.endAutoWrap(); /* GrammarOutput.t:207 */

        int alternateSpace = 0; /* GrammarOutput.t:209 */
        for (int ruleNo = 1, n = grammar.startSymbol.size(); ruleNo < n; ruleNo++) /* GrammarOutput.t:210 */
        { /* GrammarOutput.t:211 */
            startRule = grammar.rules.get(ruleNo); /* GrammarOutput.t:212 */
            out.write("\n"); /* GrammarOutput.t:213~214 */
            out.print(ruleNo); /* GrammarOutput.t:214 */
            writer.padToColumn(5); /* GrammarOutput.t:215 */
            writer.beginAutoWrap(); /* GrammarOutput.t:216 */
            if (ruleNo > 1) /* GrammarOutput.t:217 */
            { /* GrammarOutput.t:218 */
                writer.padToColumn(alternateSpace); /* GrammarOutput.t:219 */
                out.print(option.orMarker); /* GrammarOutput.t:220 */
            } /* GrammarOutput.t:221 */
            else /* GrammarOutput.t:222 */
            { /* GrammarOutput.t:223 */
                displaySymbol(grammar.restoreSymbol(grammar.retrieveString(startRule.lhs))); /* GrammarOutput.t:224 */
                out.write("::="); /* GrammarOutput.t:225 */
                alternateSpace = writer.getCurrentColumn() - 2; /* GrammarOutput.t:226 */
            } /* GrammarOutput.t:227 */
            writer.setIndentSize(writer.getCurrentColumn() + 1); /* GrammarOutput.t:228 */

            displaySymbol(grammar.restoreSymbol( /* GrammarOutput.t:230 */
                    grammar.retrieveString(grammar.rhsSym.get(startRule.rhsIndex)))); /* GrammarOutput.t:231 */
            displaySymbol(grammar.restoreSymbol( /* GrammarOutput.t:232 */
                    grammar.retrieveString(grammar.rhsSym.get(startRule.rhsIndex + 1)))); /* GrammarOutput.t:233 */
            writer.endAutoWrap(); /* GrammarOutput.t:234 */
        } /* GrammarOutput.t:235 */

        // leave a gap before listing the remaining rules. /* GrammarOutput.t:237 */
        out.write("\n"); /* GrammarOutput.t:238~239 */
        // /* GrammarOutput.t:240 */
        // Print the user specified rules. /* GrammarOutput.t:241 */
        // /* GrammarOutput.t:242 */
        for (int ruleIndex = grammar.startSymbol.size(); ruleIndex <= grammar.numRules; ruleIndex++) /* GrammarOutput.t:243 */
        { /* GrammarOutput.t:244 */
            Grammar.RuleElement ruleElement = grammar.rules.get(ruleIndex); /* GrammarOutput.t:245 */
            RuleDefinition rule = parser.rules.get(ruleElement.sourceIndex); /* GrammarOutput.t:246 */
            out.write("\n"); /* GrammarOutput.t:247~248 */
            out.print(ruleIndex); /* GrammarOutput.t:248 */
            writer.padToColumn(5); /* GrammarOutput.t:249 */
            writer.beginAutoWrap(); /* GrammarOutput.t:250 */
            if (ruleElement.isAlternateProduction()) /* GrammarOutput.t:251 */
            { /* GrammarOutput.t:252 */
                writer.padToColumn(alternateSpace); /* GrammarOutput.t:253 */
                out.print(option.orMarker); /* GrammarOutput.t:254 */
            } /* GrammarOutput.t:255 */
            else /* GrammarOutput.t:256 */
            { /* GrammarOutput.t:257 */
                displaySymbol(lexStream.nameString(rule.lhsIndex)); /* GrammarOutput.t:258 */
                int classnameIndex = rule.classnameIndex; /* GrammarOutput.t:259 */
                int arrayElementTypeIndex = rule.arrayElementTypeIndex; /* GrammarOutput.t:260 */
                if (classnameIndex != 0 && arrayElementTypeIndex == 0) /* GrammarOutput.t:261 */
                    out.print(lexStream.nameString(classnameIndex)); /* GrammarOutput.t:262 */
                else if (classnameIndex == 0 && arrayElementTypeIndex != 0) /* GrammarOutput.t:263 */
                { /* GrammarOutput.t:264 */
                    out.print(String.valueOf(option.escape) + option.escape + lexStream.nameString(arrayElementTypeIndex)); /* GrammarOutput.t:265 */
                } /* GrammarOutput.t:266 */
                else if (classnameIndex != 0 && arrayElementTypeIndex != 0) /* GrammarOutput.t:267 */
                { /* GrammarOutput.t:268 */
                    out.print(lexStream.nameString(classnameIndex) + option.escape + lexStream.nameString(arrayElementTypeIndex)); /* GrammarOutput.t:269 */
                } /* GrammarOutput.t:270 */
                else /* GrammarOutput.t:271 */
                    assert (classnameIndex == 0 && arrayElementTypeIndex == 0); /* GrammarOutput.t:272 */

                if (ruleElement.isArrowProduction()) /* GrammarOutput.t:274 */
                    out.write("->"); /* GrammarOutput.t:275 */
                else /* GrammarOutput.t:276 */
                    out.write("::="); /* GrammarOutput.t:277 */
                alternateSpace = writer.getCurrentColumn() - 2; /* GrammarOutput.t:278 */
            } /* GrammarOutput.t:279 */
            writer.setIndentSize(writer.getCurrentColumn() + 1); /* GrammarOutput.t:280 */

            for (int i = lexStream.next(rule.separatorIndex); i < rule.endRhsIndex; i = lexStream.next(i)) /* GrammarOutput.t:282 */
            { /* GrammarOutput.t:283 */
                int kind = lexStream.kind(i); /* GrammarOutput.t:284 */
                if (kind == Lpgsym.TK_SYMBOL) /* GrammarOutput.t:285 */
                    displaySymbol(lexStream.nameString(i)); /* GrammarOutput.t:286 */
                else if (kind == Lpgsym.TK_MACRO_NAME) /* GrammarOutput.t:287 */
                { /* GrammarOutput.t:288 */
                    out.print(lexStream.nameString(i)); /* GrammarOutput.t:289 */
                } /* GrammarOutput.t:290 */
                else if (kind == Lpgsym.TK_EMPTY_KEY) /* GrammarOutput.t:291 */
                { /* GrammarOutput.t:292 */
                    out.print(option.escape + "Empty"); /* GrammarOutput.t:293 */
                } /* GrammarOutput.t:294 */
            } /* GrammarOutput.t:295 */
            writer.endAutoWrap(); /* GrammarOutput.t:296 */
        } /* GrammarOutput.t:297 */

        // /* GrammarOutput.t:299 */
        // Print the Types /* GrammarOutput.t:300 */
        // /* GrammarOutput.t:301 */
        if (!parser.types.isEmpty()) /* GrammarOutput.t:302 */
        { /* GrammarOutput.t:303 */
            out.write("\n\n\nTypes:\n"); /* GrammarOutput.t:304~308 */
            alternateSpace = 0; /* GrammarOutput.t:309 */
            for (int i = 0, n = parser.types.size(); i < n; i++) /* GrammarOutput.t:310 */
            { /* GrammarOutput.t:311 */
                TypeDefinition type = parser.types.get(i); /* GrammarOutput.t:312 */
                out.write("\n    "); /* GrammarOutput.t:313~314 */
                writer.beginAutoWrap(); /* GrammarOutput.t:315 */
                if (lexStream.kind(type.separatorIndex) == Lpgsym.TK_OR_MARKER) /* GrammarOutput.t:316 */
                { /* GrammarOutput.t:317 */
                    writer.padToColumn(alternateSpace); /* GrammarOutput.t:318 */
                    out.print(option.orMarker); /* GrammarOutput.t:319 */
                } /* GrammarOutput.t:320 */
                else /* GrammarOutput.t:321 */
                { /* GrammarOutput.t:322 */
                    out.print(lexStream.nameString(type.typeIndex)); /* GrammarOutput.t:323 */
                    out.write("::="); /* GrammarOutput.t:323 */
                    alternateSpace = writer.getCurrentColumn() - 2; /* GrammarOutput.t:324 */
                } /* GrammarOutput.t:325 */
                out.print(lexStream.nameString(type.symbolIndex)); /* GrammarOutput.t:326 */
                writer.endAutoWrap(); /* GrammarOutput.t:327 */
            } /* GrammarOutput.t:328 */
        } /* GrammarOutput.t:329 */

        // /* GrammarOutput.t:331 */
        // Print the Names /* GrammarOutput.t:332 */
        // /* GrammarOutput.t:333 */
        if (option.errorMaps) /* GrammarOutput.t:334 */
        { /* GrammarOutput.t:335 */
            out.write("\n\n\nName map:\n\n"); /* GrammarOutput.t:336~341 */
            for (int symbol = 1; symbol <= grammar.numSymbols; symbol++) /* GrammarOutput.t:342 */
            { /* GrammarOutput.t:343 */
                if (grammar.symbolIndex.get(symbol).externalNameIndex != /* GrammarOutput.t:344 */
                        grammar.symbolIndex.get(grammar.acceptImage).externalNameIndex) /* GrammarOutput.t:345 */
                { /* GrammarOutput.t:346 */
                    displayNameMap(symbol); /* GrammarOutput.t:347 */
                } /* GrammarOutput.t:348 */
            } /* GrammarOutput.t:349 */
     /* GrammarOutput.t:350 */
            for (int symbol = 1; symbol <= grammar.numSymbols; symbol++) /* GrammarOutput.t:351 */
            { /* GrammarOutput.t:352 */
                if (symbol != grammar.acceptImage && grammar.symbolIndex.get(symbol).externalNameIndex == /* GrammarOutput.t:353 */
                        grammar.symbolIndex.get(grammar.acceptImage).externalNameIndex) /* GrammarOutput.t:354 */
                { /* GrammarOutput.t:355 */
                    displayNameMap(symbol); /* GrammarOutput.t:356 */
                } /* GrammarOutput.t:357 */
            } /* GrammarOutput.t:358 */
        } /* GrammarOutput.t:359 */
        out.write("\n"); /* GrammarOutput.t:360~361 */
    }

    private DispatchWriter writer = null; /* GrammarOutput.t:362 */

    private Control control = null; /* GrammarOutput.t:364 */
    private Option option = null; /* GrammarOutput.t:365 */
    private LexStream lexStream = null; /* GrammarOutput.t:366 */
    private LookupTable<String, MacroSymbol> macroTable = null; /* GrammarOutput.t:367 */
    private Grammar grammar = null; /* GrammarOutput.t:368 */
    private Parser parser = null; /* GrammarOutput.t:369 */

    private Action action = null; /* GrammarOutput.t:371 */

    void setParameters(Control control, Action action) /* GrammarOutput.t:373 */
    { /* GrammarOutput.t:374 */
        this.control = control; /* GrammarOutput.t:375 */
        this.action = action; /* GrammarOutput.t:376 */

        option = control.option; /* GrammarOutput.t:378 */
        lexStream = control.lexStream; /* GrammarOutput.t:379 */
        macroTable = control.macroTable; /* GrammarOutput.t:380 */
        grammar = control.grammar; /* GrammarOutput.t:381 */
        parser = grammar.parser; /* GrammarOutput.t:382 */

        setOut(option._syslis); /* GrammarOutput.t:384 */
        writer = option._syslis; /* GrammarOutput.t:385 */
    } /* GrammarOutput.t:386 */

    private void displaySymbol(String name) /* GrammarOutput.t:388 */
    { /* GrammarOutput.t:389 */
        int length = name.length(); /* GrammarOutput.t:390 */
        if (name.equals("\"")   || name.equals(" ")    || name.equals("--")   || name.equals("|") || /* GrammarOutput.t:391 */
            name.equals("::=")  || name.equals("::=?") || name.equals("->")   || name.equals("->?")) /* GrammarOutput.t:392 */
        { /* GrammarOutput.t:393 */
            out.print('\'' + name + '\''); /* GrammarOutput.t:394 */
        } /* GrammarOutput.t:395 */
        else if (name.charAt(0) == '<' && name.charAt(length - 1) == '>') /* GrammarOutput.t:396 */
        { /* GrammarOutput.t:397 */
            out.print(name); /* GrammarOutput.t:398 */
        } /* GrammarOutput.t:399 */
        else if (name.equals("'")) // a string consisting of 1 single quote /* GrammarOutput.t:400 */
        { /* GrammarOutput.t:401 */
            out.write("\"\'\""); /* GrammarOutput.t:402 */
        } /* GrammarOutput.t:403 */
        else if (name.indexOf('"') != -1) /* GrammarOutput.t:404 */
        { /* GrammarOutput.t:405 */
            out.print(Utility.escape(name, '\'')); /* GrammarOutput.t:406 */
        } /* GrammarOutput.t:407 */
        else if (Util.containsChar(name, "\b\t\n\f\r' ")) /* GrammarOutput.t:408 */
        { /* GrammarOutput.t:409 */
            out.print(Utility.escape(name, '"')); /* GrammarOutput.t:410 */
        } /* GrammarOutput.t:411 */
        else if (name.charAt(0) == option.escape || name.charAt(0) == '%') // does name start with user-escape or keyword-escape? /* GrammarOutput.t:412 */
        { /* GrammarOutput.t:413 */
            out.print('\'' + name + '\''); /* GrammarOutput.t:414 */
        } /* GrammarOutput.t:415 */
        else /* GrammarOutput.t:416 */
        { /* GrammarOutput.t:417 */
            out.print(name); /* GrammarOutput.t:418 */
        } /* GrammarOutput.t:419 */
    } /* GrammarOutput.t:420 */

    // /* GrammarOutput.t:422 */
    // This procedure prints the name associated with a given symbol. /* GrammarOutput.t:423 */
    // /* GrammarOutput.t:424 */
    private void displayNameMap(int symbol) /* GrammarOutput.t:425 */
    { /* GrammarOutput.t:426 */
        out.write("\n"); /* GrammarOutput.t:427~428 */
        writer.beginAutoWrap(); /* GrammarOutput.t:429 */
        out.print(grammar.retrieveString(symbol)); /* GrammarOutput.t:430 */
        out.write("::="); /* GrammarOutput.t:430 */
        out.print(grammar.retrieveName(symbol)); /* GrammarOutput.t:430 */
        writer.endAutoWrap(); /* GrammarOutput.t:431 */
    } /* GrammarOutput.t:432 */

}
